import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import ConstantKernel, RBF


class SplineRegression(object):
    def __init__(self):
        pass



class GaussianRegression(GaussianProcessRegressor):
    def __init__(self):
        super().__init__()

    def fit(self, x_train, y_train):
        super().fit(x_train, y_train)

    def predict(self, x_test, return_std=False, return_cov=False):
        """
        Parameters
        ----------
        x_test : array-like of shape (n_samples, n_features) or list of object
            Query points where the GP is evaluated.

        return_std : bool, default=False
            If True, the standard-deviation of the predictive distribution at
            the query points is returned along with the mean.

        return_cov : bool, default=False
            If True, the covariance of the joint predictive distribution at
            the query points is returned along with the mean.
        """
        self.y_pred, cov = super().predict(x_test, return_std, return_cov)
        return self.y_pred, cov

    def get_mse(self, y_test):
        """ 均方误差:MSE """
        return mean_squared_error(y_test, self.y_pred)

    def get_rmse(self, y_test):
        """ 均方根误差:RMSE """
        return np.sqrt(mean_squared_error(y_test, self.y_pred))

    def get_mae(self, y_test):
        """ 平均绝对误差:MAE """
        return mean_squared_error(y_test, self.y_pred)

    def get_score(self, y_test, sample_weight=None):
        """R^2"""
        return r2_score(y_test, self.y_pred, sample_weight=sample_weight)


if __name__ == "__main__":
    new_pumpkins = pd.read_csv("./test_file/new_pumpkins.csv")  # 利用pandas库打开csv数据
    new_pumpkins.info()  # 查看数据组织结构

    # 以南瓜的日期作为价格的预测

    # 取出南瓜类型为‘PIE TYPE’的数据
    # Y = pie_pumpkins['Price']
    # X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
    # lin_reg = LinearRegression()  # 实例化对象
    # lin_reg.fit(X_train, y_train)  # 训练线性回归模型
    # pred = lin_reg.predict(X_test)
    # mse = np.sqrt(mean_squared_error(y_test, pred))  # mean_squared_error用于计算MSE
    # print(f'RMSE指标: {mse:3.3} ({mse / np.mean(pred) * 100:3.3}%)')
    # score = lin_reg.score(X_train, y_train)
    # print('相关系数: ', score)
    # plt.scatter(X_test, y_test)
    # plt.plot(X_test, pred)
    # plt.show()

    # 以南瓜的种类作为价格的预测

    # X = pd.get_dummies(new_pumpkins['Variety'])  # 以南瓜的类别作为特征变量，并转化数据类型
    # Y = new_pumpkins['Price']  # 以价格为预测标签
    # X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)  # 以8：2的比例划分数据集与训练集
    # lin_reg = LinearRegression()  # 构建线性回归模型对象
    # lin_reg.fit(X_train, Y_train)  # 训练模型
    # pred = lin_reg.predict(X_test)  # 将测试集上的预测值存储在pred中
    # rmse = np.sqrt(mean_squared_error(Y_test, pred))  # 计算均方误差
    # print(f'RMSE指标: {rmse:3.3} ({rmse / np.mean(pred) * 100:3.3}%)')  # 输出均方误差的值以及错误率
    # score = lin_reg.score(X_train, Y_train)  # 计算回归系数
    # print('相关系数: ', score)  # 输出回归系数的值

    # 以多项式回归与预测价格
    # pie_pumpkins = new_pumpkins[new_pumpkins['Variety'] == 'PIE TYPE']
    # X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1, 1)
    # Y = pie_pumpkins['Price']
    # X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)  # 以8：2的比例划分数据集与训练集
    # pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())  # 构建自动化流程
    # pipeline.fit(X_train, Y_train)  # 训练模型
    # pred = pipeline.predict(X_test)  # 在测试集上预测结果并保存在pred变量中
    # rmse = np.sqrt(mean_squared_error(Y_test, pred))  # 计算RMSE
    # print(f'RMSE指标: {rmse:3.3} ({rmse / np.mean(pred) * 100:3.3}%)')
    # score = pipeline.score(X_train, Y_train)  # 计算相关系数
    # print('相关系数: ', score)
    # plt.scatter(X_test, Y_test)  # 绘制散点图
    # plt.plot(X_test, pred)  # 绘制回归线，若多条回归线是因为X_test是随机未排序的，排序后可尝试解决
    # plt.show()

    #  将南瓜类别代入多项式回归
    # X = pd.get_dummies(new_pumpkins['Variety'])
    # Y = new_pumpkins['Price']
    # X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2,
    #                                                     random_state=0)  # 以8：2的比例划分数据集与训练集 # setup and train the pipeline
    # pipeline = make_pipeline(PolynomialFeatures(2),
    #                          LinearRegression())  # 构建流程化工具，其中PolynomialFeatures(2)是对输入数据进行2次多项式拟合，后者为构建线性回归模型
    # pipeline.fit(X_train, Y_train)
    # pred = pipeline.predict(X_test)
    # rmse = np.sqrt(mean_squared_error(Y_test, pred))
    # print(f'RMSE指标: {rmse:3.3} ({rmse / np.mean(pred) * 100:3.3}%)')
    # score = pipeline.score(X_train, Y_train)
    # print('相关系数: ', score)

    # 多元线性回归
    # X = pd.get_dummies(new_pumpkins['Variety']) \
    #     .join(new_pumpkins['Month']) \
    #     .join(pd.get_dummies(new_pumpkins['City'])) \
    #     .join(pd.get_dummies(new_pumpkins['Package']))
    # Y = new_pumpkins['Price']
    # X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
    # lin_reg = MultiLinearRegression()
    # lin_reg.fit(X_train, Y_train)
    # predict = lin_reg.predict(X_test)
    # rmse = lin_reg.get_rmse(Y_test)
    # score = lin_reg.get_score(X_test, Y_test)
    # print(
    #     f'Mean error: {rmse:3.3} ({rmse / np.mean(predict) * 100:3.3}%)')  # 输出均方误差的值以及错误率 score = lin_reg.score(X_train,Y_train)#计算回归系数
    # print('Model determination: ', score)  # 输出回归系数的值
    # print("coef_: ",lin_reg.coef_)
    # print("intercept_: ",lin_reg.intercept_)

    from sklearn.linear_model import LinearRegression
    import numpy as np

    # 创建示例数据
    X = np.array([[1], [2], [3], [4], [5]])
    y = np.array([2, 4, 5, 4, 5])

    # 创建LinearRegression对象
    model = LinearRegression(fit_intercept=False, copy_X=True, n_jobs=None)

    # 拟合模型
    model.fit(X, y)

    # 获取系数和截距项
    coefficients = model.coef_
    intercept = model.intercept_

    print(f"系数：{coefficients}")
    print(f"截距项：{intercept}")







